/***************************************************************************
 *   Copyright (C) 2007 by Warren Kenny   *
 *   warren.kenny@gmail.com   *
 *                                                                         *
 *   This program is free software; you can redistribute it and/or modify  *
 *   it under the terms of the GNU General Public License as published by  *
 *   the Free Software Foundation; either version 2 of the License, or     *
 *   (at your option) any later version.                                   *
 *                                                                         *
 *   This program is distributed in the hope that it will be useful,       *
 *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
 *   GNU General Public License for more details.                          *
 *                                                                         *
 *   You should have received a copy of the GNU General Public License     *
 *   along with this program; if not, write to the                         *
 *   Free Software Foundation, Inc.,                                       *
 *   59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
 ***************************************************************************/
#include <otaBytePacker.h>
#include <iostream>

otaBytePacker::otaBytePacker()
{
}

bool otaBytePacker::appendBuffer( char *data, const unsigned int dataSize, const unsigned int offset, unsigned int &newOffset, const void *const writeBuffer, const unsigned int writeSize )
{
	newOffset = offset + writeSize;
	if( (data && writeBuffer) && ( offset <= dataSize ) && ( newOffset <= dataSize ) )
	{
		data += offset;
		memcpy( data, writeBuffer, writeSize );
		return true;
	}
	else
	{
		return false;
	}
	
}
	
bool otaBytePacker::removeBuffer( const char *data, const unsigned int dataSize, const unsigned int offset, unsigned int &newOffset, void *const readBuffer, const unsigned int readSize )
{
	newOffset = offset + readSize;
	if( ( data && readBuffer ) && ( offset <= dataSize ) && ( newOffset <= dataSize ) )
	{
		data += offset;
		memcpy( readBuffer, data, readSize );
		return true;
	}
	else
	{
		std::cout << "| Buffer Too Small | ";
		return false;
	}
}

bool otaBytePacker::bufferCopy( char *destination, unsigned int destinationSize, const unsigned int offset, unsigned int &newOffset, const void *source, const unsigned int sourceSize )
{
	newOffset = offset + sourceSize;
	if( ( destination && source ) && ( offset <= destinationSize ) && ( newOffset <= destinationSize ) )
	{
		destination += offset;
		memcpy( destination, source, sourceSize );
		return true;
	}
	else
	{
		return false;
	}
}

bool otaBytePacker::removeNTString( const char *data, const unsigned int dataSize, const unsigned int offset, unsigned int &newOffset, std::string &string )
{
	if( offset < dataSize )
	{
		data += offset;
		string.assign( data, (dataSize - offset) );
		newOffset = offset + string.length() + 1;
		return true;
	}
	else
	{
		return false;
	}
}

bool otaBytePacker::removeLEBinary( const char *data, const unsigned int dataSize, const unsigned int offset, unsigned int &newOffset, unsigned long &value )
{
	unsigned char indicator;
	bool ok = false;
	if( removeBasicType( data, dataSize, offset, newOffset, indicator ) )
	{
		switch(indicator)
		{
			case 254:
			{
				ok = removeBasicType( data, dataSize, newOffset, newOffset, value );		
			}
			break;
		
			case 253:
			{
				unsigned int temp;
				ok = removeBasicType( data, dataSize, newOffset, newOffset, temp );
				value = temp;
			}	
			break;
		
			case 252:
			{
				unsigned short temp;
				ok = removeBasicType( data, dataSize, newOffset, newOffset, temp );
				value = temp;
			}	
			break;
			case 251:
			{
				value = 0;
				ok = true;
			}
			break;
		
			default:
				value = indicator;
			
		}
	}
	return ok;
	
}
	
bool otaBytePacker::removeLEString( const char *data, const unsigned int dataSize, const unsigned int offset, unsigned int &newOffset, std::string &string )
{
	if( offset < dataSize )
	{
		unsigned char indicator;
		bool ok = removeBasicType( data, dataSize, offset, newOffset, indicator );
		if( ok )
		{
			switch(indicator)
			{
				case 254:
				{
					unsigned long length;
					ok = ok && removeBasicType( data, dataSize, newOffset, newOffset, length );
					newOffset += length;
					string.assign( data, length );
				}
				break;
				
				case 253:
				{
					unsigned int length;
					ok = ok && removeBasicType( data, dataSize, newOffset, newOffset, length );
					newOffset += length;
					string.assign( data, length );
				}	
				break;
				
				case 252:
				{
					unsigned short length;
					ok = ok && removeBasicType( data, dataSize, newOffset, newOffset, length );
					newOffset += length;
					string.assign( data, length );
				}	
				break;
				
				case 251:
				{
					
					string = "Unset";
					newOffset = offset + 1;
				}
				break;
				
				default:
				{
					unsigned int length = static_cast<unsigned int>(indicator);
					newOffset += length;
					string.assign( data, length );
				}
			}
			return ok;		
		}
		else
		{
			newOffset = offset;
			return false;
		}
	}
	else
	{
		return false;
	}
}
	
bool otaBytePacker::removeStaticString( const char *data, const unsigned int dataSize, const unsigned int offset, unsigned int &newOffset, unsigned int stringLength, char string[])
{
	newOffset = offset;
	for( unsigned int i = 0 ; i < stringLength ; i++ )
	{
		char element;
		if( removeBasicType( data, dataSize, newOffset, newOffset, element ) )
		{
			string[i] = element;
		}
	}
	return true;
}
	
otaBytePacker::~otaBytePacker()
{
}



